﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Hydra
{
  class Hydra
  {
    public int n, m;
    public double[] u1, u2;
    public double lambda1, lambda2, ro, mu, nu, k, c;
    public double maxT, maxX;
    public double h, dt;
    public double u1w1, u2w2, u1w2, u2w1;

    public void hydraConstr(int N, int M,double MaxT,double MaxX, double Lambda1, double Lambda2, double Ro, double Mu, double Nu, double K, double C)
    {
      maxT = MaxT;
      maxX = MaxX;
      h = maxX / N;
      dt = maxT / M;
      lambda1 = Lambda1;
      lambda2 = Lambda2;
      ro = Ro;
      mu = Mu;
      nu = Nu;
      k = K;
      c = C;
      n = N;
      m = M;
      u1 = new double[(n + 1) * (m + 1)];
      u2 = new double[(n + 1) * (m + 1)];
    }
    // 0 <= i <= n
    // 0 <= j <= m
    public int getIdx(int i, int j, int n)
    {
      return (j * (n + 1) + i);
    }
    public void solve()
    {
      for (int j = 0; j < m; j++)
      {
        for (int i = 1; i < n; i++)
        {

          u1[getIdx(i, j + 1, n)] = ((u1[getIdx(i - 1, j, n)] - 2 * u1[getIdx(i, j, n)] + u1[getIdx(i + 1, j, n)]) * lambda1 / (h * h)
            + ro - mu * u1[getIdx(i, j, n)] + k * u1[getIdx(i, j, n)] * u1[getIdx(i, j, n)] / u2[getIdx(i, j, n)]) * dt + u1[getIdx(i, j, n)];
          u2[getIdx(i, j + 1, n)] = ((u2[getIdx(i - 1, j, n)] - 2 * u2[getIdx(i, j, n)] + u2[getIdx(i + 1, j, n)]) * lambda2 / (h * h)
            - nu * u2[getIdx(i, j, n)] + c * u1[getIdx(i, j, n)] * u1[getIdx(i, j, n)]) * dt + u2[getIdx(i, j, n)];
          if ((u1[getIdx(i, j + 1, n)] > 50.0))
          {
            // ищем багу
            double bug = u1[getIdx(i, j + 1, n)];
          }
        }
      }
    }
    public void hydraSetFreq(double U1w1, double U1w2, double U2w1, double U2w2)
    {
      u1w1 = U1w1;
      u1w2 = U1w2;
      u2w1 = U2w1;
      u2w2 = U2w2;
    }
    public void useBoundarys()
    {
      // Нижняя граница
      for (int i = 0; i <= n; i++)
      {
        int j = 0;
        int idx = getIdx(i, j, n);
        u1[idx] = Math.Sin(u1w1 * i * h - u1w2 * j * dt);
        u2[idx] = Math.Sin(u2w1 * i * h - u2w2 * j * dt);
      }

      // Левая граница
      for (int j = 0; j <= m; j++)
      {
        int i = 0;
        int idx = getIdx(i, j, n);
        u1[idx] = Math.Sin(u1w1 * i * h - u1w2 * j * dt);
        u2[idx] = Math.Sin(u2w1 * i * h - u2w2 * j * dt);
      }

      // Правая граниа
      for (int j = 0; j <= m; j++)
      {
        int i = n;
        int idx = getIdx(i, j, n);
        u1[idx] = Math.Sin(u1w1 * i * h - u1w2 * j * dt);
        u2[idx] = Math.Sin(u2w1 * i * h - u2w2 * j * dt);
      }
    }
    public void solve2gu()
    {
      for (int j = 0; j < m; j++)
      {
        u1[getIdx(0, j, n)] = u1[getIdx(1, j, n)];
        u1[getIdx(n, j, n)] = u1[getIdx(n - 1, j, n)];
        u2[getIdx(0, j, n)] = u2[getIdx(1, j, n)];
        u2[getIdx(n, j, n)] = u2[getIdx(n - 1, j, n)];
        for (int i = 1; i < n; i++)
        {

          u1[getIdx(i, j + 1, n)] = ((u1[getIdx(i - 1, j, n)] - 2 * u1[getIdx(i, j, n)] + u1[getIdx(i + 1, j, n)]) * lambda1 / (h * h)
            + ro - mu * u1[getIdx(i, j, n)] + k * u1[getIdx(i, j, n)] * u1[getIdx(i, j, n)] / u2[getIdx(i, j, n)]) * dt + u1[getIdx(i, j, n)];
          u2[getIdx(i, j + 1, n)] = ((u2[getIdx(i - 1, j, n)] - 2 * u2[getIdx(i, j, n)] + u2[getIdx(i + 1, j, n)]) * lambda2 / (h * h)
            - nu * u2[getIdx(i, j, n)] + c * u1[getIdx(i, j, n)] * u1[getIdx(i, j, n)]) * dt + u2[getIdx(i, j, n)];
        }
      }
      u1[getIdx(0, m, n)] = u1[getIdx(1, m, n)];
      u1[getIdx(n, m, n)] = u1[getIdx(n - 1, m, n)];
      u2[getIdx(0, m, n)] = u2[getIdx(1, m, n)];
      u2[getIdx(n, m, n)] = u2[getIdx(n - 1, m, n)];
    }
  }
}
